﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace PlayerTest.Player.Data
{
    class Patterns
    {
        private List<string[]> patternList = new List<string[]>();

        public string this[int index]
        {
            get { return GetPatternString(index); }
        }

        public Patterns()
        {
            SetPatterns();
        }

        /// <summary>
        /// 입력된 문장이 어느 패턴에 해당하는지 반환합니다.
        /// </summary>
        /// <param name="sentence">검사할 문장</param>
        /// <returns>패턴 번호(-1:해당하는 패턴 없음)</returns>
        public int Match(string sentence)
        {
            //int result = 0;

            // 축약형을 전처리합니다.
            string str = PreProcess(sentence);

            for (int i = 0; i < patternList.Count; i++)
            {
                if (Check(str, patternList[i]))
                {
                    return i;
                }
            }

            return -1;
        }

        /// <summary>
        /// 문자열 전처리
        /// </summary>
        /// <param name="sentence"></param>
        private string PreProcess(string str)
        {
            string sentence = str;
            // 축약형 제거
            sentence = sentence.Replace("n't", " not");
            sentence = sentence.Replace("'ve", " have");
            sentence = sentence.Replace("'d", " would");
            sentence = sentence.Replace("'m", " am");

            // 특수문자 제거
            sentence = sentence.Replace("?", " ");
            sentence = sentence.Replace("!", " ");
            sentence = sentence.Replace(".", " ");
            sentence = sentence.Replace(",", " ");

            return sentence;
        }

        private bool Check(string sentence, string[] pattern)
        {
            string[] words = sentence.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            int checkedPosition = 0;
            int prevPosition = 0;
            int distance = 0;
            bool matched = false;

            // distance 없는 비교
            // int pos = sentence.IndexOf(patternPiece, checkedPosition, StringComparison.OrdinalIgnoreCase);

            // 패턴 조각 루프
            foreach (string patternPiece in pattern)
            {
                matched = false;
                for (int i = checkedPosition; i < words.Length; i++)
                {
                    // 패턴 조각이 해당 문장에 포함되었는가?
                    int pos = string.Compare(patternPiece, words[i], true);
                    if (pos == 0)
                    {
                        // 포함되었다면 문장의 다음 단어부터 검색 시작
                        distance += checkedPosition - prevPosition;
                        prevPosition = checkedPosition;
                        checkedPosition = i + 1;
                        matched = true;
                        break;
                    }
                }
                if (!matched) return false;
            }

            if (distance > 3)
                return false;

            return true;
        }

        /// <summary>
        /// patterns.txt파일에서 패턴을 읽어옵니다
        /// </summary>
        private void SetPatterns()
        {
            FileInfo fi = new FileInfo("patterns.txt");
            StreamReader reader = fi.OpenText();
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                string[] words = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                patternList.Add(words);
            }
        }

        /// <summary>
        /// string[] 형식의 패턴을 string 문자열로 반환합니다.
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private string GetPatternString(int index)
        {
            if (index >= 0 && index < patternList.Count)
            {
                string str = "";
                for (int i = 0; i < patternList[index].Length; i++)
                {
                    if (i != 0) str += " ";
                    str += patternList[index][i];
                }
                return str;
            }

            return null;
        }
    }
}
